#include "inmp441_driver.h"
#include <driver/i2s.h>

#define I2S_WS 25  // LRCLK
#define I2S_SCK 26 // BCLK
#define I2S_SD 22  // DATA
#define I2S_NUM I2S_NUM_0

#define SAMPLE_RATE 44100
#define I2S_BITS I2S_BITS_PER_SAMPLE_32BIT
#define DMA_BUF_COUNT 8
#define DMA_BUF_LEN 128

void inmp441Setup()
{
    Serial.println("INMP441 初始化...");
    // ---------------- I2S 配置 ----------------
    i2s_config_t i2s_config = {}; // 初始化 I2S 配置结构体，{} 表示清零
    i2s_config.mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX);
    // 设置 I2S 工作模式：主机模式（MASTER）+ 接收模式（RX），用于从麦克风读取数据
    i2s_config.sample_rate = SAMPLE_RATE;
    // 采样率，例如 16000 Hz，决定每秒采样多少次
    i2s_config.bits_per_sample = I2S_BITS;
    // 每次采样的位数，例如 16 位
    i2s_config.channel_format = I2S_CHANNEL_FMT_ONLY_LEFT;
    // 通道格式，这里只使用左声道
    i2s_config.communication_format = I2S_COMM_FORMAT_STAND_I2S;
    // I2S 通信协议格式，这里使用标准 I2S
    i2s_config.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1;
    // 中断分配标志，使用等级 1 的中断
    i2s_config.dma_buf_count = DMA_BUF_COUNT;
    // DMA 缓冲区数量，用于存储采集的数据
    i2s_config.dma_buf_len = DMA_BUF_LEN;
    // 每个 DMA 缓冲区的长度
    i2s_config.use_apll = false;
    // 是否使用 APLL 时钟源，这里不使用
    i2s_config.tx_desc_auto_clear = false;
    // 发送描述符自动清零，这里不使用（因为只接收）
    i2s_config.fixed_mclk = 0;
    // 固定主时钟频率，0 表示使用默认值

    // ---------------- I2S 引脚配置 ----------------
    i2s_pin_config_t pin_config = {}; // 初始化 I2S 引脚结构体
    pin_config.bck_io_num = I2S_SCK;  // BCLK（比特时钟）连接的 GPIO
    pin_config.ws_io_num = I2S_WS;    // LRCLK / WS（左右声道选择信号）连接的 GPIO
    pin_config.data_out_num = I2S_PIN_NO_CHANGE;
    // 数据输出引脚，因为只接收麦克风，所以不用输出
    pin_config.data_in_num = I2S_SD;
    // 数据输入引脚，连接麦克风数据线

    // ---------------- 安装 I2S 驱动 ----------------
    i2s_driver_install(I2S_NUM, &i2s_config, 0, NULL);
    // 安装 I2S 驱动，绑定配置到指定 I2S 端口（I2S_NUM）

    i2s_set_pin(I2S_NUM, &pin_config);
    // 设置 I2S 引脚配置

    Serial.println("INMP441 已初始化完成");
}

void inmp441Loop()
{
    int32_t buffer[DMA_BUF_LEN];
    size_t bytes_read = 0;

    if (i2s_read(I2S_NUM, buffer, sizeof(buffer), &bytes_read, portMAX_DELAY) == ESP_OK && bytes_read > 0)
    {
        int samples = bytes_read / 4;
        int32_t max_val = 0;

        for (int i = 0; i < samples; i++)
        {
            int32_t val = abs(buffer[i]);
            if (val > max_val)
                max_val = val;
        }

        Serial.print("音量: ");
        Serial.println(max_val);
    }
}